/**
 * 摄像头扫描器模块
 * 负责处理摄像头访问、视频流管理和图像数据获取
 */

class CameraScanner {
    constructor() {
        this.video = null;
        this.canvas = null;
        this.ctx = null;
        this.stream = null;
        this.drawFrameId = null; // 添加绘制帧ID
        this.lastDrawTime = 0; // 上次绘制时间
        this.drawInterval = 33; // 绘制间隔约30fps
        this.config = {
            width: 640,
            height: 480,
            facingMode: 'environment' // 后置摄像头
        };
    }

    /**
     * 初始化摄像头
     * @param {HTMLCanvasElement} canvasElement - canvas元素
     * @param {Object} config - 配置选项
     */
    async init(canvasElement, config = {}) {
        try {
            this.canvas = canvasElement;
            this.ctx = this.canvas.getContext('2d');
            this.config = { ...this.config, ...config };

            // 获取video元素（由UIManager创建）
            this.video = document.querySelector('.jz-scanner-video');
            if (!this.video) {
                throw new Error('Video元素未找到');
            }

            // 获取摄像头流
            await this.startCamera();
            
            console.log('摄像头初始化成功');
        } catch (error) {
            console.error('摄像头初始化失败:', error);
            throw error;
        }
    }

    /**
     * 启动摄像头
     */
    async startCamera() {
        try {
            const constraints = {
                video: {
                    width: { ideal: this.config.width },
                    height: { ideal: this.config.height },
                    facingMode: { ideal: this.config.facingMode }
                },
                audio: false
            };

            this.stream = await navigator.mediaDevices.getUserMedia(constraints);
            this.video.srcObject = this.stream;
            
            // 等待视频开始播放
            await new Promise((resolve, reject) => {
                this.video.onloadedmetadata = () => {
                    this.video.play().then(resolve).catch(reject);
                };
                this.video.onerror = reject;
            });

            // 设置canvas尺寸以匹配video
            this.canvas.width = this.video.videoWidth;
            this.canvas.height = this.video.videoHeight;

            // 开始绘制视频帧到canvas（用于二维码识别）
            this.drawVideoFrame();

            console.log('摄像头启动成功', {
                videoWidth: this.video.videoWidth,
                videoHeight: this.video.videoHeight
            });
        } catch (error) {
            console.error('启动摄像头失败:', error);
            throw new Error('无法访问摄像头: ' + error.message);
        }
    }

    /**
     * 绘制视频帧到canvas（用于二维码识别）- 优化版本
     */
    drawVideoFrame() {
        if (!this.video || !this.canvas || !this.ctx) {
            return;
        }

        const now = Date.now();
        
        // 控制绘制频率，减少CPU占用
        if (now - this.lastDrawTime >= this.drawInterval) {
            if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) {
                try {
                    // 将video画面绘制到canvas（用于二维码识别）
                    this.ctx.drawImage(
                        this.video, 
                        0, 0, 
                        this.canvas.width, 
                        this.canvas.height
                    );
                    this.lastDrawTime = now;
                } catch (error) {
                    console.warn('绘制视频帧失败:', error);
                }
            }
        }

        // 继续绘制下一帧
        this.drawFrameId = requestAnimationFrame(() => {
            this.drawVideoFrame();
        });
    }

    /**
     * 获取当前图像数据
     * @returns {ImageData|null} 图像数据
     */
    getImageData() {
        if (!this.canvas || !this.ctx) {
            return null;
        }

        try {
            return this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
        } catch (error) {
            console.error('获取图像数据失败:', error);
            return null;
        }
    }

    /**
     * 停止摄像头
     */
    async stop() {
        try {
            // 停止绘制循环
            if (this.drawFrameId) {
                cancelAnimationFrame(this.drawFrameId);
                this.drawFrameId = null;
            }

            if (this.stream) {
                this.stream.getTracks().forEach(track => track.stop());
                this.stream = null;
            }

            if (this.video) {
                this.video.srcObject = null;
                // 注意：video元素由UIManager管理，不在这里删除
                this.video = null;
            }

            // 重置状态
            this.lastDrawTime = 0;

            console.log('摄像头已停止');
        } catch (error) {
            console.error('停止摄像头失败:', error);
        }
    }

    /**
     * 检查摄像头权限
     */
    async checkCameraPermission() {
        try {
            // 检查是否为HTTPS环境
            if (location.protocol !== 'https:' && location.hostname !== 'localhost' && location.hostname !== '127.0.0.1') {
                throw new Error('摄像头访问需要HTTPS环境，当前为HTTP协议。请使用HTTPS访问或在localhost环境下测试。');
            }

            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                throw new Error('当前浏览器不支持摄像头访问功能');
            }

            // 尝试获取权限状态
            if (navigator.permissions) {
                const permission = await navigator.permissions.query({ name: 'camera' });
                if (permission.state === 'denied') {
                    throw new Error('摄像头权限被拒绝，请在浏览器设置中允许摄像头访问');
                }
            }

            // 尝试访问摄像头验证权限
            const stream = await navigator.mediaDevices.getUserMedia({ 
                video: { facingMode: 'environment' } 
            });
            stream.getTracks().forEach(track => track.stop());
            return true;
        } catch (error) {
            console.error('检查摄像头权限失败:', error);
            
            // 根据错误类型提供更友好的提示
            if (error.name === 'NotAllowedError') {
                throw new Error('摄像头权限被拒绝，请允许访问摄像头权限');
            } else if (error.name === 'NotFoundError') {
                throw new Error('未检测到摄像头设备');
            } else if (error.name === 'NotSupportedError' || error.name === 'OverconstrainedError') {
                throw new Error('摄像头不支持请求的配置');
            } else if (error.message.includes('HTTPS')) {
                throw error; // 直接抛出HTTPS相关错误
            } else {
                throw new Error('无法访问摄像头: ' + error.message);
            }
        }
    }

    /**
     * 检查是否支持摄像头
     */
    static async isSupported() {
        return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
    }

    /**
     * 获取可用摄像头列表
     */
    static async getCameras() {
        try {
            if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
                return [];
            }

            const devices = await navigator.mediaDevices.enumerateDevices();
            return devices.filter(device => device.kind === 'videoinput');
        } catch (error) {
            console.error('获取摄像头列表失败:', error);
            return [];
        }
    }
}

export default CameraScanner; 